use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use rusqlite::{params, Connection};
use serde::{Deserialize, Serialize};
use std::sync::Mutex;
use reqwest::Client;

#[derive(Serialize, Deserialize)]
struct Config {
    id: u32,
    name: String,
    value: String,
}

#[derive(Serialize, Deserialize)]
struct SyncRequest {
    config_id: u32,
    agent_url: String,
}

#[derive(Serialize, Deserialize)]
struct SyncStatus {
    config_id: u32,
    status: String,
}

// 数据库管理器
struct DbManager {
    conn: Mutex<Connection>,
}

impl DbManager {
    fn new() -> Self {
        let conn = Connection::open("config.db").expect("Failed to open database");
        conn.execute(
            "CREATE TABLE IF NOT EXISTS configs (
                id INTEGER PRIMARY KEY,
                name TEXT NOT NULL,
                value TEXT NOT NULL
            )",
            [],
        ).expect("Failed to create configs table");

        conn.execute(
            "CREATE TABLE IF NOT EXISTS sync_status (
                config_id INTEGER PRIMARY KEY,
                status TEXT NOT NULL
            )",
            [],
        ).expect("Failed to create sync_status table");

        DbManager {
            conn: Mutex::new(conn),
        }
    }

    // 创建新配置
    fn create_config(&self, config: &Config) -> rusqlite::Result<()> {
        let conn = self.conn.lock().unwrap();
        conn.execute(
            "INSERT INTO configs (name, value) VALUES (?1, ?2)",
            params![config.name, config.value],
        )?;
        Ok(())
    }

    // 获取配置
    fn get_config(&self, config_id: u32) -> Option<Config> {
        let conn = self.conn.lock().unwrap();
        let mut stmt = conn.prepare("SELECT id, name, value FROM configs WHERE id = ?1").ok()?;
        let config_iter = stmt.query_map(params![config_id], |row| {
            Ok(Config {
                id: row.get(0)?,
                name: row.get(1)?,
                value: row.get(2)?,
            })
        }).ok()?;

        for config in config_iter {
            return Some(config.ok()?);
        }

        None
    }

    // 更新配置
    fn update_config(&self, config_id: u32, config: &Config) -> rusqlite::Result<()> {
        let conn = self.conn.lock().unwrap();
        conn.execute(
            "UPDATE configs SET name = ?1, value = ?2 WHERE id = ?3",
            params![config.name, config.value, config_id],
        )?;
        Ok(())
    }

    // 删除配置
    fn delete_config(&self, config_id: u32) -> rusqlite::Result<()> {
        let conn = self.conn.lock().unwrap();
        conn.execute("DELETE FROM configs WHERE id = ?1", params![config_id])?;
        Ok(())
    }

    // 记录同步状态
    fn update_sync_status(&self, config_id: u32, status: &str) -> rusqlite::Result<()> {
        let conn = self.conn.lock().unwrap();
        conn.execute(
            "INSERT OR REPLACE INTO sync_status (config_id, status) VALUES (?1, ?2)",
            params![config_id, status],
        )?;
        Ok(())
    }

    // 获取同步状态
    fn get_sync_status(&self, config_id: u32) -> Option<String> {
        let conn = self.conn.lock().unwrap();
        let mut stmt = conn.prepare("SELECT status FROM sync_status WHERE config_id = ?1").ok()?;
        stmt.query_row(params![config_id], |row| row.get(0)).ok()
    }
}

// 配置同步请求
async fn sync_config_to_agent(
    sync_request: web::Json<SyncRequest>,
    db_manager: web::Data<DbManager>,
) -> impl Responder {
    let config = db_manager.get_config(sync_request.config_id);

    if let Some(config) = config {
        // 将配置发送给 agent 端
        let client = Client::new();
        let agent_url = format!("{}/apply_config", sync_request.agent_url);
        match client.post(&agent_url)
            .json(&config)
            .send()
            .await {
                Ok(response) if response.status().is_success() => {
                    db_manager.update_sync_status(config.id, "Success").unwrap();
                    return HttpResponse::Ok().json(SyncStatus {
                        config_id: config.id,
                        status: "Success".to_string(),
                    });
                }
                Ok(response) => {
                    db_manager.update_sync_status(config.id, "Failed").unwrap();
                    return HttpResponse::InternalServerError().body(format!("Agent responded with error: {}", response.status()));
                }
                Err(err) => {
                    db_manager.update_sync_status(config.id, "Failed").unwrap();
                    return HttpResponse::InternalServerError().body(format!("Failed to send config to agent: {:?}", err));
                }
            }
    } else {
        HttpResponse::NotFound().body("Config not found")
    }
}

// 获取同步状态
async fn get_sync_status(path: web::Path<u32>, db_manager: web::Data<DbManager>) -> impl Responder {
    let config_id = path.into_inner();
    if let Some(status) = db_manager.get_sync_status(config_id) {
        HttpResponse::Ok().json(SyncStatus {
            config_id,
            status,
        })
    } else {
        HttpResponse::NotFound().body("Status not found")
    }
}

// 创建新配置
async fn create_config(config: web::Json<Config>, db_manager: web::Data<DbManager>) -> impl Responder {
    match db_manager.create_config(&config) {
        Ok(_) => HttpResponse::Ok().body("Config created"),
        Err(_) => HttpResponse::InternalServerError().body("Failed to create config"),
    }
}

// 获取配置
async fn get_config(path: web::Path<u32>, db_manager: web::Data<DbManager>) -> impl Responder {
    let config_id = path.into_inner();
    if let Some(config) = db_manager.get_config(config_id) {
        HttpResponse::Ok().json(config)
    } else {
        HttpResponse::NotFound().body("Config not found")
    }
}

// 更新配置
async fn update_config(path: web::Path<u32>, config: web::Json<Config>, db_manager: web::Data<DbManager>) -> impl Responder {
    let config_id = path.into_inner();
    match db_manager.update_config(config_id, &config) {
        Ok(_) => HttpResponse::Ok().body("Config updated"),
        Err(_) => HttpResponse::InternalServerError().body("Failed to update config"),
    }
}

// 删除配置
async fn delete_config(path: web::Path<u32>, db_manager: web::Data<DbManager>) -> impl Responder {
    let config_id = path.into_inner();
    match db_manager.delete_config(config_id) {
        Ok(_) => HttpResponse::Ok().body("Config deleted"),
        Err(_) => HttpResponse::InternalServerError().body("Failed to delete config"),
    }
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let db_manager = web::Data::new(DbManager::new());

    HttpServer::new(move || {
        App::new()
            .app_data(db_manager.clone())
            .route("/config", web::post().to(create_config))
            .route("/config/{id}", web::get().to(get_config))
            .route("/config/{id}", web::put().to(update_config))
            .route("/config/{id}", web::delete().to(delete_config))
            .route("/sync", web::post().to(sync_config_to_agent))  // 同步配置
            .route("/sync_status/{id}", web::get().to(get_sync_status))  // 查看同步状态
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}
